//package net.xdclass.service.impl;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import lombok.extern.slf4j.Slf4j;
//import net.xdclass.enums.BizCodeEnum;
//import net.xdclass.enums.CouponCategoryEnum;
//import net.xdclass.enums.CouponPublishEnum;
//import net.xdclass.enums.CouponStateEnum;
//import net.xdclass.exception.BizException;
//import net.xdclass.interceptor.LoginInterceptor;
//import net.xdclass.mapper.CouponMapper;
//import net.xdclass.mapper.CouponRecordMapper;
//import net.xdclass.model.CouponDO;
//import net.xdclass.model.CouponRecordDO;
//import net.xdclass.model.LoginUser;
//import net.xdclass.service.CouponService;
//import net.xdclass.util.CommonUtil;
//import net.xdclass.util.JsonData;
//import net.xdclass.vo.CouponVo;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.data.redis.core.script.DefaultRedisScript;
//import org.springframework.stereotype.Service;
//
//import java.time.Duration;
//import java.util.Arrays;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.Map;
//import java.util.concurrent.TimeUnit;
//import java.util.stream.Collectors;
//
///**
// * @author : zhen.xue
// * @date : 2021-05-03 22:21
// */
//@Slf4j
//@Service
//public class CouponServiceImplbak implements CouponService {
//
//
//    @Autowired
//    private CouponMapper couponMapper;
//
//    @Autowired
//    private CouponRecordMapper couponRecordMapper;
//
//    @Autowired
//    private StringRedisTemplate redisTemplate;
//
//
//    @Override
//    public Map<String, Object> pageCouponActivity(int page, int size) {
//        Page<CouponDO> pageInfo = new Page<>(page,size);
//        Page<CouponDO> couponDOPage = couponMapper.selectPage(pageInfo, new QueryWrapper<CouponDO>()
//                .eq("publish", CouponPublishEnum.PUBLISH)
//                .eq("category", CouponCategoryEnum.PROMOTION)
//                .orderByDesc("create_time"));
//        HashMap<String, Object> pageMap = new HashMap<>(3);
//        pageMap.put("total_record",couponDOPage.getTotal());
//        pageMap.put("total_page",couponDOPage.getPages());
//        pageMap.put("current_date",couponDOPage.getRecords().stream().map(obj->{
//            CouponVo couponVo = new CouponVo();
//            BeanUtils.copyProperties(obj,couponVo);
//            return couponVo;
//        }).collect(Collectors.toList()));
//        return pageMap;
//    }
//
//    @Override
//    public JsonData addCoupon(long couponId, CouponCategoryEnum category) {
//        //    领取优惠卷
//        //  1 获取优惠卷是否存在
//        //  2 校验优惠券是否可以领取:时间 库存 超时 限制
//        //  3 扣减库存
//        //  4 保存领卷记录
//        LoginUser user = LoginInterceptor.threadLocal.get();
//
//        String uuid = CommonUtil.generateUUID();
//        String loackKey = "lock:coupon:"+couponId;
//        // 避免锁过期将过期时间设置的久一点
//        Boolean lockFlag = redisTemplate.opsForValue().setIfAbsent(loackKey, uuid, Duration.ofMinutes(30));
//        if(lockFlag != null && lockFlag){
//            // 加锁成功
//            log.info("加锁成功:{}",couponId);
//            try{
//                // 执行业务逻辑
//                CouponDO couponDO = couponMapper.selectOne(new QueryWrapper<CouponDO>()
//                        .eq("id", couponId)
//                        .eq("cateGory", category.name()));
//                if(couponDO == null){
//                    throw new BizException(BizCodeEnum.COUPON_NO_EXITS);
//                }
//                // 优惠券是够可以领取
//                this.checkCoupon(couponDO,user.getId());
//                // 构建领券记录
//                CouponRecordDO couponRecordDO = new CouponRecordDO();
//                BeanUtils.copyProperties(couponDO,couponRecordDO);
//                couponRecordDO.setCreateTime(new Date());
//                couponRecordDO.setUseState(CouponStateEnum.NEW.name());
//                couponRecordDO.setUserId(user.getId());
//                couponRecordDO.setCouponId(couponId);
//                couponRecordDO.setUserName(user.getName());
//                couponRecordDO.setId(null);
//                // 扣减库存
//                int rows =  couponMapper.reduceStock(couponId);
//                if(rows == 1){
//                    // 库存扣减成功保存记录
//                    couponRecordMapper.insert(couponRecordDO);
//                }else{
//                    log.warn("发放优惠券失败:{},用户:{}",couponDO,user);
//                    throw new BizException(BizCodeEnum.COUPON_NO_STOCK);
//                }
//            }finally {
//                // 释放锁
//                String script = "if redis.call('get',KEYS[1]) == ARGV[1]" +
//                        "then" +
//                        "return redis.call('del',KEYS[1])" +
//                        "else" +
//                        "return 0" +
//                        "end";
//                Integer result = redisTemplate.execute(new DefaultRedisScript<>(script, Integer.class), Arrays.asList(loackKey), uuid);
//                log.info("解锁couponId:{},result:{}",couponId,result);
//            }
//        }else{
//            // 睡眠一下，自旋,根据业务规则可以进行次数限制对锁进行增加并判断这里使用睡眠
//            try {
//                TimeUnit.SECONDS.sleep(1);
//            } catch (InterruptedException e) {
//                log.error("自旋失败",e);
//            }
//            addCoupon(couponId,category);
//        }
//        return JsonData.buildSuccess();
//    }
//
//
//    /**
//     * 检查优惠卷是否可以领取
//     * @param couponDO 优惠卷
//     * @param id 用户id
//     */
//    private void checkCoupon(CouponDO couponDO, Long id) {
//        // 库存是否充足
//        if(couponDO.getStock()<=0){
//            throw new BizException(BizCodeEnum.COUPON_NO_STOCK);
//        }
//        if(!CouponPublishEnum.PUBLISH.name().equals(couponDO.getPublish())){
//            throw new BizException(BizCodeEnum.COUPON_GET_FAIL);
//        }
//        // 是否在领取时间范围
//        long time = CommonUtil.getCurrentTimeMillis();
//        long startTime = couponDO.getStartTime().getTime();
//        long endTime = couponDO.getEndTime().getTime();
//        if(time<startTime || time >endTime){
//            throw new BizException(BizCodeEnum.COUPON_OUT_OF_TIME);
//        }
//        // 用户是否超过限制
//        Integer recordCound = couponRecordMapper.selectCount(new QueryWrapper<CouponRecordDO>().eq("coupon_id", couponDO.getId()).eq("user_id", id));
//        if(recordCound >= couponDO.getUserLimit()){
//            throw new BizException(BizCodeEnum.COUPON_OUT_OF_LIMIT);
//        }
//    }
//}